﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.Linq;

namespace ShortcutToolbox.Core
{
    public static class I18N
    {
        private static ReadOnlyDictionary<string, Language> _langs;
        private static Language _current;

        public static event EventHandler<LanguageChangedEventArgs> Changed;

        public static dynamic Current
        {
            get
            {
                lock (_langs)
                    return _current;
            }
        }

        static I18N()
        {
            Dictionary<string, Language> langs = new Dictionary<string, Language>();
            try
            {
                string[][] folders = new string[][] {
                    new string[]{ "lang", "*.xml" },
                    new string[]{ Path.Combine("plugins", "lang"), "*.xml" },
                    new string[]{ Utils.GetUserProfileDirectoryPath("plugins", "lang"), "*.xml" },
                };

                foreach (string[] item in folders)
                {
                    if (!Directory.Exists(item[0]))
                        continue;
                    string[] files = Directory.GetFiles(item[0], item[1]);
                    if (files == null)
                        continue;
                    foreach (string file in files)
                    {
                        try
                        {
                            dynamic lang = Language.Create(file);
                            if (string.IsNullOrEmpty(lang.name))
                                lang.name = Path.GetFileNameWithoutExtension(file);
                            if (langs.ContainsKey(lang.name))
                            {
                                Language org = langs[lang.name];
                                foreach (string p in lang.Properties)
                                    org[p] = lang[p];
                            }
                            else
                                langs.Add(lang.name, lang);
                        }
                        catch (Exception ex)
                        {
                            Logging.Error(ex);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.Error(ex);
            }

            _langs = new ReadOnlyDictionary<string, Language>(langs);
            _current = GetLangByCulture();
        }

        public static IList<Language> GetLangList()
        {
            return new List<Language>(_langs.Values);
        }

        public static Language GetLangByCulture()
        {
            Language lang = null;
            string culture = CultureInfo.CurrentCulture.IetfLanguageTag;
            culture = culture.Replace("-", "_");
            if (_langs.ContainsKey(culture))
                lang = _langs[culture];
            else if (culture.StartsWith("en", StringComparison.OrdinalIgnoreCase) && _langs.ContainsKey("en"))
                lang = _langs["en"];
            else if (culture.StartsWith("zh", StringComparison.OrdinalIgnoreCase))
            {
                if (_langs.ContainsKey("zh"))
                    lang = _langs["zh"];
                else if (_langs.ContainsKey("zh_CN"))
                    lang = _langs["zh_CN"];
            }

            if (lang == null && _langs.Count > 0)
                lang = _langs.Values.First();

            return lang;
        }

        public static Language GetLang(string name)
        {
            if (name != null && _langs.ContainsKey(name))
                return _langs[name];
            return null;
        }

        public static void SetLang(Language lang)
        {
            bool fireEvent = false;
            if (_current != lang)
            {
                lock (_langs)
                {
                    if (_current != lang)
                    {
                        _current = lang;
                        fireEvent = true;
                    }
                }
            }
            if (fireEvent && Changed != null)
                Changed.Invoke(null, new LanguageChangedEventArgs(lang));
        }

    }
}
